package com.sec.etech.bpm.job;

import cn.hutool.core.map.MapUtil;
import com.sec.etech.sys.cal.service.WorkCalService;
import lombok.extern.slf4j.Slf4j;
import net.javacrumbs.shedlock.spring.annotation.SchedulerLock;
import org.openbpm.form.util.JdbcTemplateUtil;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class EtechTaskExtJob {
    @Resource
    private WorkCalService workCalService;


    //@Scheduled(cron = "10 58 */2 * * ? ")
    //@SchedulerLock(name = "calTaskRemainDaysDaily", lockAtMostFor="30M", lockAtLeastFor="30M")
    public void calTaskRemainDaysDaily() {
        // 剩余天数计算相关逻辑
        // 计算期望完成日期： workCalService.getWorkDayByDay([createTime],[workDay])
        // 计算当天剩余天数=工作天数-已过去工作日，其中 已过去工作日：workCalService.getWorkDaysByTime([createTime],[today])
        log.info("开始剩余天数计算");
        JdbcTemplate jdbcTemplate = JdbcTemplateUtil.getJdbcTemplate("dataSourceDefault");
        String sql1 = "update bpm_task_opinion o\n" +
                "set o.remain_days_ = (select sum(isWorkDay_) from c_work_calendar where day_ between now() and o.plan_complete_day_)\n" +
                "  , o.cal_days_time_=now()\n" +
                "where o.status_='awaiting_check' and (o.cal_days_time_ is null or o.cal_days_time_ <=(NOW() - interval 2 hour))" +
                " and o.plan_complete_day_>=now()";
        String sql2 = "update bpm_task_opinion o\n" +
                "set o.remain_days_ = (select -1*sum(isWorkDay_) from c_work_calendar where day_ between o.plan_complete_day_ and now())\n" +
                "    , o.cal_days_time_=now()\n" +
                "    where o.status_='awaiting_check' and (o.cal_days_time_ is null or o.cal_days_time_ <=(NOW() - interval 2 hour)) " +
                " and o.plan_complete_day_<now()";
        // fix 去掉条件，0天强制刷新
        String sql3 = "update bpm_task_opinion o\n" +
                "set o.remain_days_=0\n" +
                "    , o.cal_days_time_=now()\n" +
                "where o.status_='awaiting_check' " +
                " and DATE_FORMAT(o.plan_complete_day_,'%Y-%m-%d')=DATE_FORMAT(NOW(),'%Y-%m-%d')";
        jdbcTemplate.execute(sql1);
        jdbcTemplate.execute(sql2);
        jdbcTemplate.execute(sql3);

        log.info("完成剩余天数计算");
    }

    public void calTaskRemainDaysDaily2() {
        // 剩余天数计算相关逻辑
        // 计算期望完成日期： workCalService.getWorkDayByDay([createTime],[workDay])
        // 计算当天剩余天数=工作天数-已过去工作日，其中 已过去工作日：workCalService.getWorkDaysByTime([createTime],[today])
        log.info("开始剩余天数计算");
        JdbcTemplate jdbcTemplate = JdbcTemplateUtil.getJdbcTemplate("dataSourceDefault");
        // id_, create_time_, plan_workdays_, plan_complete_day_, remain_days_, cal_days_time_
        String sql = "select t.* " +
                "from bpm_task_opinion t " +
                "where t.status_='awaiting_check' " +
                //"where t.status_='awaiting_check' and t.plan_workdays_ is not null " +
                "and (t.cal_days_time_ is null or t.cal_days_time_ <=(NOW() - interval 23 hour))";
        String updateSql1 = "update bpm_task_opinion set remain_days_=?, cal_days_time_=now() where id_=?";
        List<Object[]> updateArg1 = new ArrayList<>();
        String updateSql2 = "update bpm_task_opinion set plan_complete_day_=?, remain_days_=?, cal_days_time_=now() where id_=?";
        List<Object[]> updateArg2 = new ArrayList<>();


        List<Map<String, Object>> list = jdbcTemplate.queryForList(sql);
        log.debug("剩余天数计算：总数为"+list.size());
        for (Map<String, Object> row : list) {
            // 工作天数, 创建时间
            Long id = MapUtil.getLong(row, "id_");
            // 检查剩余工作天数
            int remainDays = MapUtil.getInt(row, "remain_days_");

            // 检查计划完成时间
            boolean needUpdatePlanCompleteDay = false;
            Date completeDay = MapUtil.getDate(row, "plan_complete_day_");
            if (completeDay == null) {
                // 如缺少预期完成时间则重新计算
                needUpdatePlanCompleteDay = true;
                int workdays = 0;
                try {
                    workdays = MapUtil.getInt(row, "plan_workdays_");
                }catch (Exception e){

                }
                Date createTime = MapUtil.getDate(row, "create_time_");
                completeDay = workCalService.getWorkDayByDays(createTime, workdays);
                completeDay = WorkCalService.endOfDay(completeDay);  //当前结束时间
                remainDays = workdays - workCalService.getWorkDaysByTime4remainDay(createTime, new Date());
            } else {
                // 根据计划完成时间反推剩余天数
                // JOB也需要适应 根据"计划送审时间"更新"预期完成时间"
                // https://etech.coding.net/p/etech-all/bug-tracking/issues/2440/detail
                remainDays = workCalService.getWorkDaysByTime4remainDay(new Date(), completeDay);
            }

            if (needUpdatePlanCompleteDay) {
                updateArg2.add(new Object[]{completeDay, remainDays, id});
            } else {
                updateArg1.add(new Object[]{remainDays, id});
            }
        }//end for
        if (!updateArg1.isEmpty()) {
            jdbcTemplate.batchUpdate(updateSql1, updateArg1);
        }
        if (!updateArg2.isEmpty()) {
            jdbcTemplate.batchUpdate(updateSql2, updateArg2);
        }
        log.info("完成剩余天数计算");
    }

    //@Scheduled(fixedDelay = 30000)
    public void scheduleFixedDelayTask() {
        System.out.println("EtechTaskExtJob Fixed delay task - " + System.currentTimeMillis() / 1000);
    }
}
